/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.czone.myfacebook;

import java.util.List;

import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
import android.widget.LinearLayout;

public class MainActivity extends FragmentActivity {
    private static final String TAG = "MainActivity";

    //
    // FACEBOOKDATAMANAGER
    //
    private FaceBookDataManager mFaceBookDataManager;

    // FRAGMENT VALUE
    private Fragment[] mFragments = new Fragment[Define.FRAGMENT_COUNT];
    private int mCurrentfragmentIndex = Define.SPLASH;

    //
    // MENU VALUE
    //
    private MenuItem mSettingMenuItem;
    private MenuItem mFeedviewMenuItem;
    private MenuItem mRequestFeedMenuItem;

    //
    // LODING VIEW
    //
    private LoadingView mLoadingView;

    private boolean mIsResumed = false;

    /**
     * Main Message Process
     */
    // private Handler mHandler = new Handler() {
    // public void handleMessage(Message msg) {
    // switch (msg.what) {
    // case Define.MAINACTIVITY_REQUEST_FEEDDATA :
    // break;
    // }
    // }
    // };

    private UiLifecycleHelper mUiHelper;
    private Session.StatusCallback mCallback = new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        CLog.i(TAG, "onCreate Start");

        super.onCreate(savedInstanceState);

        mUiHelper = new UiLifecycleHelper(this, mCallback);
        mUiHelper.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        mLoadingView = new LoadingView(this, (LinearLayout) findViewById(R.id.main_layout));

        FragmentManager fm = getSupportFragmentManager();
        mFragments[Define.SPLASH] = fm.findFragmentById(R.id.splashFragment);
        mFragments[Define.SELECTION] = fm.findFragmentById(R.id.selectionFragment);
        mFragments[Define.SETTINGS] = fm.findFragmentById(R.id.userSettingsFragment);
        mFragments[Define.FEEDVIEW] = fm.findFragmentById(R.id.feedviewfragment);

        FragmentTransaction transaction = fm.beginTransaction();
        for (int i = 0; i < mFragments.length; i++) {
            transaction.hide(mFragments[i]);
        }
        transaction.commit();

        // mFaceBookDataManager = FaceBookDataManager.getInstance();
        // if (mFaceBookDataManager != null)
        // mFaceBookDataManager.setValues(mFragments, mLoadingView,
        // mMainCallBack);
        mFaceBookDataManager = new FaceBookDataManager(mFragments, mLoadingView, mMainCallBack);

        CLog.i(TAG, "onCreate End");
    }

    private void showFragment(int fragmentIndex, boolean addToBackStack) {
        CLog.i(TAG, "showFragment Start fragmentIndex = " + fragmentIndex);

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();

        for (int i = 0; i < mFragments.length; i++) {
            if (i == fragmentIndex) {
                mCurrentfragmentIndex = i;
                transaction.show(mFragments[i]);
            } else {
                transaction.hide(mFragments[i]);
            }
        }

        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.commitAllowingStateLoss();

        CLog.i(TAG, "showFragment End");
    }

    private MainCallBack mMainCallBack = new MainCallBack();

    public class MainCallBack {
        public void onScrollCallback(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            CLog.i(TAG, "onScrollCallback() :: firstVisibleItem = " + firstVisibleItem + " visibleItemCount = " + visibleItemCount + " totalItemCount = " + totalItemCount);

            int count = totalItemCount - visibleItemCount;

            if (firstVisibleItem >= count && totalItemCount != 0 && !mFaceBookDataManager.getLockListView()) {
                CLog.i(TAG, "Loading next items");
                // add next item call method
                mFaceBookDataManager.doRequestPage(Define.REQUEST_NEXT_PAGE);
            }
        }

        public void onCompleteRequest() {
            CLog.i(TAG, "onCompleteRequest()");
            if (mIsResumed) {
                showFragment(Define.FEEDVIEW, false);
            }
        }
    }

    @Override
    public void onResume() {
        CLog.i(TAG, "onResume");

        super.onResume();
        mUiHelper.onResume();
        mIsResumed = true;
    }

    @Override
    public void onPause() {
        CLog.i(TAG, "onPause");

        super.onPause();
        mUiHelper.onPause();
        mIsResumed = false;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        CLog.i(TAG, "onActivityResult");

        super.onActivityResult(requestCode, resultCode, data);
        mUiHelper.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case Define.REAUTH_ACTIVITY_CODE:
                Session session = Session.getActiveSession();
                if (session != null) {
                    session.onActivityResult(this, requestCode, resultCode, data);
                }
                break;
        }
    }

    @Override
    public void onDestroy() {
        CLog.i(TAG, "onDestroy");

        super.onDestroy();
        if (mUiHelper != null) {
            mUiHelper.onDestroy();
            mUiHelper = null;
        }

        if (mFaceBookDataManager != null) {
            mFaceBookDataManager.onDestroy();
            mFaceBookDataManager = null;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mUiHelper.onSaveInstanceState(outState);
    }

    public void requestReadPermissions(Activity activity, Session session, List<String> permissions, int requestCode) {
        if (session != null) {
            Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(activity, permissions).setRequestCode(requestCode);
            session.requestNewReadPermissions(reauthRequest);
        }
    }

    private void onSessionStateChange(Session session, SessionState state, Exception exception) {
        CLog.i(TAG, "onSessionStateChange Start");

        if (mIsResumed) {
            FragmentManager fm = getSupportFragmentManager();
            int backStackSize = fm.getBackStackEntryCount();

            for (int i = 0; i < backStackSize; i++)
                fm.popBackStack();

            if (state.isOpened()) {
                handleAnnounce();

                // showFragment(Define.SELECTION, false);
                if (!mFaceBookDataManager.getLockListView()) {
                    mFaceBookDataManager.doRequestFeedData();
                }
            } else if (state.isClosed()) {
                showFragment(Define.SPLASH, false);
            }
        }

        CLog.d(TAG, "onSessionStateChange End");
    }
    
    private void handleAnnounce() {
        Session session = Session.getActiveSession();

        if (session == null || !session.isOpened()) {
            return;
        }
        
        List<String> permissions = session.getPermissions();
        if (!permissions.containsAll(Define.PERMISSIONS)) {
            session.addCallback(mCallback);
            requestReadPermissions(this, session, Define.PERMISSIONS, Define.REAUTH_ACTIVITY_CODE);
        }
    }
    @Override
    protected void onResumeFragments() {
        CLog.i(TAG, "onResumeFragments Start");

        super.onResumeFragments();
        Session session = Session.getActiveSession();

        if (session != null && session.isOpened()) {
            handleAnnounce();
            mFaceBookDataManager.doRequestFeedData();
        } else {
            showFragment(Define.SPLASH, false);
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (mFragments[Define.SELECTION].isVisible()) {
            if (menu.size() == 0) {
                mSettingMenuItem = menu.add(R.string.settings);
                mFeedviewMenuItem = menu.add(R.string.feedview);
                mRequestFeedMenuItem = menu.add(R.string.requetsfeeddata);
            }

            return true;
        } else {
            menu.clear();
            mSettingMenuItem = null;
            mFeedviewMenuItem = null;
            mRequestFeedMenuItem = null;
        }

        return false;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.equals(mSettingMenuItem)) {
            showFragment(Define.SETTINGS, true);
            return true;
        } else if (item.equals(mRequestFeedMenuItem)) {
            // sendRequestPage(Define.REQUEST_NEXT_PAGE);
        } else if (item.equals(mFeedviewMenuItem)) {
            showFragment(Define.FEEDVIEW, false);
        }
        return false;
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        boolean retVal = false;

        if (mCurrentfragmentIndex == Define.FEEDVIEW) {
            retVal = ((FeedViewFragment) mFragments[Define.FEEDVIEW]).keyUp(keyCode, event);
        }

        return retVal ? true : super.onKeyUp(keyCode, event);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        CLog.d(TAG, "onConfigurationChanged() E");
    }
}